#include "Udp_Client.hpp"
#include <memory>
#include <pthread.h>

static void Usage(std::string proc)
{
    std::cout << "\nUsage:\n\t" << proc << " ip port\n" << std::endl;
}

//收消息
void* Recv(void* args)
{   
    int sock = *(static_cast<int*>(args));
    while(true)
    {
        char buff[2048];
        struct sockaddr_in receiver_temp;
        socklen_t len = sizeof(receiver_temp);
        memset(&receiver_temp, 0, sizeof(receiver_temp));

        int n = recvfrom(sock, buff, sizeof(buff) - 1, 0, (struct sockaddr*)&receiver_temp, &len);
        if(n > 0)
        {
            buff[n] = '\0';
        }

        std::string ip = inet_ntoa(receiver_temp.sin_addr);
        uint16_t port = ntohs(receiver_temp.sin_port);
        std::cout << ip << ":" << port << "> " << buff << std::endl;
    }
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        exit(USAGE_FAIL);
    }
    
    std::unique_ptr<UdpClient> up_ucli(new UdpClient(argv[1], std::stoi(argv[2])));

    //主线程执行发消息，子线程执行收消息
    up_ucli->InitClient();

    int sock = up_ucli->GetSock();
    pthread_t tid;
    pthread_create(&tid, nullptr, Recv, &sock);

    up_ucli->Send();
    // std::string _ip = argv[1];
    // uint16_t _port = atoi(argv[2]);

    // //创建套接字
    // int _sock = socket(AF_INET, SOCK_DGRAM, 0);
    // if(_sock < 0)
    // {
    //     perror("create socket fail");
    //     exit(SOCKET_FAIL);
    // }

    // //服务器方--收信息方
    // struct sockaddr_in receiver;
    // memset(&receiver, 0, sizeof(receiver));
    // receiver.sin_family = AF_INET;
    // receiver.sin_port = htons(_port);
    // receiver.sin_addr.s_addr = inet_addr(_ip.c_str());

    // pthread_t tid;
    // pthread_create(&tid, nullptr, Recv, &_sock);

    // while (true)
    // {
    //     // 多线程化？？

    //     // 用户输入
    //     std::string message;
    //     std::cerr << "Please Enter Your Message# "; // 2
    //     // std::cin >> message;

    //     std::getline(std::cin, message);
    //     // 什么时候bind的？在我们首次系统调用发送数据的时候，OS会在底层随机选择clientport+自己的IP,1. bind 2. 构建发送的数据报文
    //     // 发送
    //     sendto(_sock, message.c_str(), message.size(), 0, (struct sockaddr *)&receiver, sizeof(receiver));
    // }

    return 0;
}